﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Data;

using Uber.Collections;
using Uber.Messages;
using Uber.Storage;
using Uber.HabboHotel.Support;

namespace Uber.HabboHotel.GameClients
{
    partial class GameClientManager
    {
        public SafeList<GameClient> Clients;

        public int ClientCount
        {
            get
            {
                return this.Clients.Count;
            }
        }

        public GameClientManager()
        {
            this.Clients = new SafeList<GameClient>();
        }

        public void Clear()
        {
            this.Clients = null;
            this.Clients = new SafeList<GameClient>();
        }

        public GameClient GetClient(uint ClientId)
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                if (Client.ClientId == ClientId)
                {
                    return Client;
                }
            }

            return null;
        }

        public void StartClient(uint ClientId)
        {
            GameClient newClient = new GameClient(ClientId);

            if (newClient == null) { return; }

            Clients.Add(newClient);

            newClient.StartConnection();
        }

        public void StopClient(uint ClientId)
        {
            GameClient Client = GetClient(ClientId);

            if (Client == null)
            {
                return;
            }

            UberEnvironment.GetConnectionManager().DropConnection(ClientId);

            Client.Stop();
            Clients.Remove(Client);
        }

        public GameClient GetClientByHabbo(uint HabboId)
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                if (Client.GetHabbo() != null)
                {
                    if (Client.GetHabbo().Id == HabboId)
                    {
                        return Client;
                    }
                }
            }

            return null;
        }

        public GameClient GetClientByHabbo(string Name)
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                if (Client.GetHabbo() != null)
                {
                    if (Client.GetHabbo().Username.ToLower() == Name.ToLower())
                    {
                        return Client;
                    }
                }
            }

            return null;
        }

        public void BroadcastMessage(ServerMessage Message)
        {
            this.BroadcastMessage(Message, "");
        }

        public void BroadcastMessage(ServerMessage Message, string FuseRequirement)
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                try
                {
                    if (FuseRequirement.Length > 0)
                    {
                        if (Client.GetHabbo() == null || !Client.GetHabbo().HasFuse(FuseRequirement))
                        {
                            continue;
                        }
                    }

                    Client.SendMessage(Message);
                }
                catch (Exception) { }
            }
        }

        public void CheckEffects()
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                if (Client.GetHabbo() != null)
                {
                    Client.GetHabbo().GetAvatarEffectsInventoryComponent().CheckExpired();
                }
            }
        }

        public void LogClonesOut(string Username)
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                if (Client.GetHabbo() != null && Client.GetHabbo().Username.ToLower() == Username.ToLower())
                {
                    Client.Disconnect();
                }
            }
        }

        public string GetNameById(uint Id)
        {
            GameClient Cl = GetClientByHabbo(Id);

            if (Cl != null)
            {
                return Cl.GetHabbo().Username;
            }

            DataRow Row = null;

            using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient())
            {
                Row = dbClient.ReadDataRow("SELECT username FROM users WHERE id = '" + Id + "' LIMIT 1");
            }

            if (Row == null)
            {
                return "Unknown User";
            }

            return (string)Row[0];
        }

        public uint GetIdByName(string Name)
        {
            GameClient Cl = GetClientByHabbo(Name);

            if (Cl != null)
            {
                return Cl.GetHabbo().Id;
            }

            DataRow Row = null;

            using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient())
            {
                Row = dbClient.ReadDataRow("SELECT id FROM users WHERE username = '" + Name + "' LIMIT 1");
            }

            if (Row == null)
            {
                return 0;
            }

            return (uint)Row[0];
        }

        public void CheckForAllBanConflicts()
        {
            var ConflictsFound = new Dictionary<GameClient, ModerationBanException>();

            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                try
                {
                    UberEnvironment.GetGame().GetBanManager().CheckForBanConflicts(Client);
                }
                catch (ModerationBanException e)
                {
                    ConflictsFound.Add(Client, e);
                }
            }

            foreach (KeyValuePair<GameClient, ModerationBanException> Data in ConflictsFound)
            {
                Data.Key.SendBanMessage(Data.Value.Message);
                Data.Key.Disconnect();
            }
        }

        public void CheckPixelUpdates()
        {
            for (int i = 0; i < Clients.Count; i++)
            {
                GameClient Client = Clients[i];

                if (Client == null) { continue; }

                if (Client.GetHabbo() != null)
                {
                    if (UberEnvironment.GetGame().GetPixelManager().NeedsUpdate(Client))
                    {
                        UberEnvironment.GetGame().GetPixelManager().GivePixels(Client);
                    }

                    if (Client.GetHabbo().IsUltraVip)
                    {
                        Client.GetHabbo().CheckOnlineAchievements();
                    }
                }
            }
        }
    }
}
